package com.goldlok.seed

import akka.actor.{Actor, ActorLogging}
import akka.cluster.Cluster
import akka.cluster.ClusterEvent._

/**
  * @author galudisu
  */
class ClusterSeedListener extends Actor with ActorLogging {
  val cluster = Cluster(context.system)

  // subscribe to cluster changes, re-subscribe when restart
  override def preStart(): Unit = {

    // 订阅集群事件和新节点的加入
    cluster.subscribe(self, initialStateMode = InitialStateAsEvents, classOf[MemberEvent], classOf[UnreachableMember])
  }

  override def postStop(): Unit = cluster.unsubscribe(self)

  def receive = {

    // 订阅者Actor对象接收到的第一个事件是CurrentClusterState，该事件含有集群构成后的全部状态
    case state: CurrentClusterState =>
      log.info(s"==> members: ${state.members}, leader address: ${state.leader}, front role leader: ${state.roleLeader("front")}, unreachable members: ${state.unreachable}")

    case MemberUp(member) =>
      log.info("==> Member is Up: {}", member.address)

    case MemberExited(member) =>
      log.info("==> Member is Exited: {}", member)

    case MemberRemoved(member, previousStatus) =>
      log.info("==> Member is Removed: {} after {}", member.address, previousStatus)

    case UnreachableMember(member) =>
      log.info("==> Member detected as unreachable: {}", member)

    case ReachableMember(member) =>
      log.info("==> Member detected as reachable: {}", member)

    case _: MemberEvent => // ignore
  }
}